//
//  TestReversiBoard.m
//  Reversi
//
//  Created by 成瀬 龍人 on 2/6/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "TestReversiBoard.h"
#import "ReversiBoard.h"

@implementation TestReversiBoard
- (void)setUp{
}

- (void)tearDown{
}

- (void)testUtil{
	ReversiBoardPosition* pos = [[ReversiBoardPosition alloc] initWithInt:8:8];
	uint64 mask = 0x0000000000000001;
	STAssertTrue(mask == pos2mask(pos), @"require %l64x but %l64x", mask, pos2mask(pos));
	STAssertTrue(mask == index2mask(64), @"require %l64x but %l64x", mask, index2mask(64));
	pos = [[ReversiBoardPosition alloc] initWithInt:1:1];
	mask = 0x8000000000000000;
	STAssertTrue(mask == pos2mask(pos), @"require %l64x but %l64x", mask, pos2mask(pos));
	STAssertTrue(mask == index2mask(1), @"require %l64x but %l64x", mask, index2mask(1));
	pos = [[ReversiBoardPosition alloc] initWithInt:4:4];
	mask = 0x0000001000000000;
	STAssertTrue(mask == pos2mask(pos), @"require %l64x but %l64x", mask, pos2mask(pos));
	STAssertTrue(mask == index2mask(28), @"require %l64x but %l64x", mask, index2mask(28));
}

- (void)testReversi{
	ReversiBoard* board = [[ReversiBoard alloc] initForGame];
	STAssertTrue([[board description] isEqual:@"\
++++++++\n\
++++++++\n\
++++++++\n\
+++@O+++\n\
+++O@+++\n\
++++++++\n\
++++++++\n\
++++++++\n"],
				   @"initForGame %@", [board description]);
	ReversiBoardPosition* pos = [[ReversiBoardPosition alloc] initWithInt:5:3];
	STAssertTrue([board isPutOK:REVERSI_STONE_BLACK:pos],@"isPutOk");
	pos = [[ReversiBoardPosition alloc] initWithInt:6:4];
	STAssertTrue([board isPutOK:REVERSI_STONE_BLACK:pos],@"isPutOk");
	pos = [[ReversiBoardPosition alloc] initWithInt:5:3];
	STAssertTrue([board isPutOK:REVERSI_STONE_BLACK:pos],@"isPutOk");
	pos = [[ReversiBoardPosition alloc] initWithInt:6:4];
	STAssertTrue([board isPutOK:REVERSI_STONE_BLACK:pos],@"isPutOk");
	pos = [[ReversiBoardPosition alloc] initWithInt:6:3];
	STAssertFalse([board isPutOK:REVERSI_STONE_BLACK:pos],@"isPutOk");
	STAssertEquals([board numberOf:REVERSI_STONE_BLACK], 2, @"number of black");
	STAssertEquals([board numberOf:REVERSI_STONE_WHITE], 2, @"number of white");
	STAssertEquals([board numberOfFree], 60, @"number of free");
	pos = [[ReversiBoardPosition alloc] initWithInt:6:6];
	[board put:REVERSI_STONE_WHITE:pos];
	STAssertTrue([board is:REVERSI_STONE_WHITE:pos],@"is white");
	pos = [[ReversiBoardPosition alloc] initWithInt:3:3];
	STAssertTrue([board isPutOK:REVERSI_STONE_WHITE:pos],@"isPutOk");
	STAssertFalse([board isFull],@"is full");
	STAssertFalse([board isGameOver],@"is full");	
}

- (void)testPutStone{
	NSMutableString* s = [[NSMutableString alloc] init];
	[s appendString:@"@OO@OOO@"];
	[s appendString:@"OOOOOOOO"];
	[s appendString:@"OOOOOOOO"];
	[s appendString:@"@OO++OO@"];
	[s appendString:@"@OO++OO@"];
	[s appendString:@"OOOOOOOO"];
	[s appendString:@"OOOOOOOO"];
	[s appendString:@"@OOO@OO@"];
	ReversiBoard* board = [[ReversiBoard alloc] initWithString:s];
	STAssertTrue([[board description] isEqual:@"\
@OO@OOO@\n\
OOOOOOOO\n\
OOOOOOOO\n\
@OO++OO@\n\
@OO++OO@\n\
OOOOOOOO\n\
OOOOOOOO\n\
@OOO@OO@\n"],
				 @"initWithString %@", [board description]);
	ReversiBoardPosition* pos = [[ReversiBoardPosition alloc] initWithInt:4:4];
	STAssertTrue([board isFree:pos],@"isFree");
	STAssertTrue([board isPutOK:REVERSI_STONE_BLACK:pos],@"isPutOk");
	STAssertEquals([board numberOfWillChange:REVERSI_STONE_BLACK :pos], 6, @"number of change");
	STAssertEquals((int)[[board putAndChangeEx:REVERSI_STONE_BLACK :pos] count], 3, @"change %d", (int)[[board putAndChangeEx:REVERSI_STONE_BLACK :pos] count]);
	pos = [[ReversiBoardPosition alloc] initWithInt:5:4];
	STAssertTrue([board isFree:pos],@"isFree");
	STAssertTrue([board isPutOK:REVERSI_STONE_BLACK:pos],@"isPutOk");
	STAssertEquals([board numberOfWillChange:REVERSI_STONE_BLACK :pos], 4, @"number of change");
	STAssertEquals((int)[[board putAndChangeEx:REVERSI_STONE_BLACK :pos] count], 2, @"change %d", (int)[[board putAndChangeEx:REVERSI_STONE_BLACK :pos] count]);
	pos = [[ReversiBoardPosition alloc] initWithInt:4:5];
	STAssertTrue([board isFree:pos],@"isFree");
	STAssertTrue([board isPutOK:REVERSI_STONE_BLACK:pos],@"isPutOk");
	STAssertEquals([board numberOfWillChange:REVERSI_STONE_BLACK :pos], 4, @"number of change");
	STAssertEquals((int)[[board putAndChangeEx:REVERSI_STONE_BLACK :pos] count], 2, @"change %d", (int)[[board putAndChangeEx:REVERSI_STONE_BLACK :pos] count]);
	pos = [[ReversiBoardPosition alloc] initWithInt:5:5];
	STAssertTrue([board isFree:pos],@"isFree");
	STAssertTrue([board isPutOK:REVERSI_STONE_BLACK:pos],@"isPutOk");
	STAssertEquals([board numberOfWillChange:REVERSI_STONE_BLACK :pos], 6, @"number of change");
	STAssertEquals((int)[[board putAndChangeEx:REVERSI_STONE_BLACK :pos] count], 3, @"change %d", (int)[[board putAndChangeEx:REVERSI_STONE_BLACK :pos] count]);
	pos = [[ReversiBoardPosition alloc] initWithInt:5:4];
	STAssertFalse([board isPutOK:REVERSI_STONE_WHITE:pos],@"isPutOk");
	
	[board initWithString:s];
	pos = [[ReversiBoardPosition alloc] initWithInt:4:4];
	STAssertFalse([board isPutOK:REVERSI_STONE_WHITE:pos],@"isPutOk");
	pos = [[ReversiBoardPosition alloc] initWithInt:5:4];
	STAssertFalse([board isPutOK:REVERSI_STONE_WHITE:pos],@"isPutOk");
	pos = [[ReversiBoardPosition alloc] initWithInt:4:5];
	STAssertFalse([board isPutOK:REVERSI_STONE_WHITE:pos],@"isPutOk");
	pos = [[ReversiBoardPosition alloc] initWithInt:5:5];
	STAssertFalse([board isPutOK:REVERSI_STONE_WHITE:pos],@"isPutOk");
	
	STAssertEquals((int)[[board allocatablePositions:REVERSI_STONE_BLACK] count], 4, @"allocatable black num %d",(int)[[board allocatablePositions:REVERSI_STONE_BLACK] count]);
	STAssertEquals((int)[[board allocatablePositions:REVERSI_STONE_WHITE] count], 0, @"allocatable white num %d",(int)[[board allocatablePositions:REVERSI_STONE_WHITE] count]);
	
	[board allClear];
	pos = [[ReversiBoardPosition alloc] initWithInt:5:5];
	[board put:REVERSI_STONE_BLACK:pos];
	STAssertTrue([board isGameOver],@"game over");
	
	s = [[NSMutableString alloc] init];
	[s appendString:@"++++++++"];
	[s appendString:@"++++++++"];
	[s appendString:@"++++++++"];
	[s appendString:@"O++++++O"];
	[s appendString:@"O+++O@+@"];
	[s appendString:@"++++++++"];
	[s appendString:@"++++++++"];
	[s appendString:@"++++++++"];
	board = [[ReversiBoard alloc] initWithString:s];
	pos = [[ReversiBoardPosition alloc] initWithInt:7:5];
	STAssertEquals((int)[[board putAndChangeEx:REVERSI_STONE_WHITE :pos] count], 1, @"change");
	
	s = [[NSMutableString alloc] init];
	[s appendString:@"++++++++"];
	[s appendString:@"@++++++@"];
	[s appendString:@"@++++++@"];
	[s appendString:@"O++++++@"];
	[s appendString:@"O+O@+++@"];
	[s appendString:@"O++++++@"];
	[s appendString:@"+++++++@"];
	[s appendString:@"++++++++"];
	board = [[ReversiBoard alloc] initWithString:s];
	pos = [[ReversiBoardPosition alloc] initWithInt:2:5];
	STAssertEquals((int)[[board putAndChangeEx:REVERSI_STONE_BLACK :pos] count], 1, @"change");
	
}
@end
